﻿using MIO.Client.Protocal;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MIO.Client.Handler
{
    public class SendHandler
    {
        private Thread thSend = null;
        private bool isStopped = false;
        private IOClient client;
        private Socket socket;
        private ConcurrentQueue<Packet> packetQueue = null;

        public SendHandler(IOClient client,Socket socket, ConcurrentQueue<Packet> packetQueue)
        {
            this.client = client;
            this.socket = socket;
            this.packetQueue = packetQueue;
        }

        public void start()
        {
            isStopped = false;
            if (thSend != null)
                stop();
            thSend = new Thread(handler);
            thSend.IsBackground = true;
            thSend.Start();
        }

        private void handler()
        {
            
            while (!isStopped)
            {
                Task.Factory.StartNew(() => {
                    Packet packet = null;
                    if (packetQueue.TryDequeue(out packet))
                { 
                   
                        if (client.UdpSocket != null && packet != null && (packet.Type != PacketType.EVENT_MESSAGE || client.Connected))
                        {
                            try
                            { 
                                if (client?.UdpSocket?.Send(packet.toBytes()) > 0)
                                {
                                    if (packet.Ack && !string.IsNullOrEmpty(packet.AckId) && packet.Type == PacketType.EVENT_MESSAGE)
                                    {
                                        client.AckManager.registerAck(packet.SessionId, packet);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                            }
                        }

                    }
                });
            }
        }

        public void stop()
        {
            isStopped = true;
            if (thSend != null)
            {
                try
                {
                    while (thSend.IsAlive) { }
                    thSend.Abort();
                    thSend = null;
                }
                catch { }
            }
            Packet discardPacket = null;
            while (packetQueue.Count > 0)
            {
                packetQueue.TryDequeue(out discardPacket);
            }
        }
    }
}
